package com.yuan.base.widget.iosDialog;

import android.app.Dialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.TextView;

import com.kaopiz.kprogresshud.Determinate;
import com.kaopiz.kprogresshud.Indeterminate;
import com.yuan.base.R;

/**
 * 重写优化加载框的库，源码存在内存泄漏问题
 */

public class IosProgress {

	public static final int SPIN_INDETERMINATE = 1;
	public static final int PIE_DETERMINATE = 2;
	public static final int ANNULAR_DETERMINATE = 3;
	public static final int BAR_DETERMINATE = 4;

	// To avoid redundant APIs, make the HUD as a wrapper class around a Dialog
	private IosProgress.ProgressDialog mProgressDialog;
	private float mDimAmount;
	private int mWindowColor;
	private float mCornerRadius;
	private Context mContext;

	private int mAnimateSpeed;

	private int mMaxProgress;
	private boolean mIsAutoDismiss;

	private int mGraceTimeMs;
	private Handler mGraceTimer;
	private boolean mFinished;

	public IosProgress(Context context) {
		mContext = context;
		mProgressDialog = new IosProgress.ProgressDialog(context);
		mDimAmount = 0;
		//noinspection deprecation
		mWindowColor = context.getResources().getColor(R.color.kprogresshud_default_color);
		mAnimateSpeed = 1;
		mCornerRadius = 10;
		mIsAutoDismiss = true;
		mGraceTimeMs = 0;
		mFinished = false;

		mProgressDialog.setView(new SpinView(mContext));
	}

	/**
	 * Create a new HUD. Have the same effect as the constructor.
	 * For convenient only.
	 * @param context Activity context that the HUD bound to
	 * @return An unique HUD instance
	 */
	public static IosProgress create(Context context) {
		return new IosProgress(context);
	}

	/**
	 * Create a new HUD. specify the HUD style (if you use a custom view, you need {@code KProgressHUD.create(Context context)}).
	 * @param context Activity context that the HUD bound to
	 * @param style   One of the IosProgress.Style values
	 * @return An unique HUD instance
	 */
	public static IosProgress create(Context context, int style) {
		return new IosProgress(context).setStyle(style);
	}

	/**
	 * Specify the HUD style (not needed if you use a custom view)
	 * @param style One of the KProgressHUD.Style values
	 * @return Current HUD
	 */
	public IosProgress setStyle(int style) {
		View view = null;
		switch (style) {
			case SPIN_INDETERMINATE:
				view = new SpinView(mContext);
				break;
			case PIE_DETERMINATE:
				view = new PieView(mContext);
				break;
			case ANNULAR_DETERMINATE:
				view = new AnnularView(mContext);
				break;
			case BAR_DETERMINATE:
				view = new BarView(mContext);
				break;
			// No custom view style here, because view will be added later
		}
		mProgressDialog.setView(view);
		return this;
	}

	/**
	 * Specify the dim area around the HUD, like in Dialog
	 * @param dimAmount May take value from 0 to 1. Default to 0 (no dimming)
	 * @return Current HUD
	 */
	public IosProgress setDimAmount(float dimAmount) {
		if (dimAmount >= 0 && dimAmount <= 1) {
			mDimAmount = dimAmount;
		}
		return this;
	}

	/**
	 * Set HUD size. If not the HUD view will use WRAP_CONTENT instead
	 * @param width  in dp
	 * @param height in dp
	 * @return Current HUD
	 */
	public IosProgress setSize(int width, int height) {
		mProgressDialog.setSize(width, height);
		return this;
	}

	/**
	 * @param color ARGB color
	 * @return Current HUD
	 * @deprecated As of release 1.1.0, replaced by {@link #setBackgroundColor(int)}
	 */
	@Deprecated
	public IosProgress setWindowColor(int color) {
		mWindowColor = color;
		return this;
	}

	/**
	 * Specify the HUD background color
	 * @param color ARGB color
	 * @return Current HUD
	 */
	public IosProgress setBackgroundColor(int color) {
		mWindowColor = color;
		return this;
	}

	/**
	 * Specify corner radius of the HUD (default is 10)
	 * @param radius Corner radius in dp
	 * @return Current HUD
	 */
	public IosProgress setCornerRadius(float radius) {
		mCornerRadius = radius;
		return this;
	}

	/**
	 * Change animation speed relative to default. Used with indeterminate style
	 * @param scale Default is 1. If you want double the speed, set the param at 2.
	 * @return Current HUD
	 */
	public IosProgress setAnimationSpeed(int scale) {
		mAnimateSpeed = scale;
		return this;
	}

	/**
	 * Optional label to be displayed.
	 * @return Current HUD
	 */
	public IosProgress setLabel(String label) {
		mProgressDialog.setLabel(label);
		return this;
	}

	/**
	 * Optional label to be displayed
	 * @return Current HUD
	 */
	public IosProgress setLabel(String label, int color) {
		mProgressDialog.setLabel(label, color);
		return this;
	}

	/**
	 * Optional detail description to be displayed on the HUD
	 * @return Current HUD
	 */
	public IosProgress setDetailsLabel(String detailsLabel) {
		mProgressDialog.setDetailsLabel(detailsLabel);
		return this;
	}

	/**
	 * Optional detail description to be displayed
	 * @return Current HUD
	 */
	public IosProgress setDetailsLabel(String detailsLabel, int color) {
		mProgressDialog.setDetailsLabel(detailsLabel, color);
		return this;
	}

	/**
	 * Max value for use in one of the determinate styles
	 * @return Current HUD
	 */
	public IosProgress setMaxProgress(int maxProgress) {
		mMaxProgress = maxProgress;
		return this;
	}

	/**
	 * Set current progress. Only have effect when use with a determinate style, or a custom
	 * view which implements Determinate interface.
	 */
	public void setProgress(int progress) {
		mProgressDialog.setProgress(progress);
	}

	/**
	 * Provide a custom view to be displayed.
	 * @param view Must not be null
	 * @return Current HUD
	 */
	public IosProgress setCustomView(View view) {
		if (view != null) {
			mProgressDialog.setView(view);
		} else {
			throw new RuntimeException("Custom view must not be null!");
		}
		return this;
	}

	/**
	 * Specify whether this HUD can be cancelled by using back button (default is false)
	 * @return Current HUD
	 */
	public IosProgress setCancellable(boolean isCancellable) {
		mProgressDialog.setCancelable(isCancellable);
		return this;
	}

	/**
	 * Specify whether this HUD closes itself if progress reaches max. Default is true.
	 * @return Current HUD
	 */
	public IosProgress setAutoDismiss(boolean isAutoDismiss) {
		mIsAutoDismiss = isAutoDismiss;
		return this;
	}

	/**
	 * Grace period is the time (in milliseconds) that the invoked method may be run without
	 * showing the HUD. If the task finishes before the grace time runs out, the HUD will
	 * not be shown at all.
	 * This may be used to prevent HUD display for very short tasks.
	 * Defaults to 0 (no grace time).
	 * @param graceTimeMs Grace time in milliseconds
	 * @return Current HUD
	 */
	public IosProgress setGraceTime(int graceTimeMs) {
		mGraceTimeMs = graceTimeMs;
		return this;
	}

	public IosProgress show() {
		if (!isShowing()) {
			mFinished = false;
			if (mGraceTimeMs == 0) {
				mProgressDialog.show();
			} else {
				mGraceTimer = new Handler();
				mGraceTimer.postDelayed(new Runnable() {
					@Override
					public void run() {
						if (mProgressDialog != null && !mFinished) {
							mProgressDialog.show();
						}
					}
				}, mGraceTimeMs);
			}
		}
		return this;
	}

	public boolean isShowing() {
		return mProgressDialog != null && mProgressDialog.isShowing();
	}

	public void dismiss() {
		mFinished = true;
		if (mProgressDialog != null && mProgressDialog.isShowing()) {
			mProgressDialog.dismiss();
		}
		if (mGraceTimer != null) {
			mGraceTimer.removeCallbacksAndMessages(null);
			mGraceTimer = null;
		}
	}

	private class ProgressDialog extends Dialog {

		private Determinate mDeterminateView;
		private Indeterminate mIndeterminateView;
		private View mView;
		private TextView mLabelText;
		private TextView mDetailsText;
		private String mLabel;
		private String mDetailsLabel;
		private FrameLayout mCustomViewContainer;
		private BackgroundLayout mBackgroundLayout;
		private int mWidth, mHeight;
		private int mLabelColor = Color.WHITE;
		private int mDetailColor = Color.WHITE;

		public ProgressDialog(Context context) {
			super(context);
		}

		@Override
		protected void onCreate(Bundle savedInstanceState) {
			super.onCreate(savedInstanceState);
			requestWindowFeature(Window.FEATURE_NO_TITLE);
			setContentView(R.layout.ios_progresshud_hud);

			Window window = getWindow();
			window.setBackgroundDrawable(new ColorDrawable(0));
			window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
			WindowManager.LayoutParams layoutParams = window.getAttributes();
			layoutParams.dimAmount = mDimAmount;
			layoutParams.gravity = Gravity.CENTER;
			window.setAttributes(layoutParams);

			setCanceledOnTouchOutside(false);

			initViews();
		}

		private void initViews() {
			mBackgroundLayout = (BackgroundLayout) findViewById(R.id.background);
			mBackgroundLayout.setBaseColor(mWindowColor);
			mBackgroundLayout.setCornerRadius(mCornerRadius);
			if (mWidth != 0) {
				updateBackgroundSize();
			}

			mCustomViewContainer = (FrameLayout) findViewById(R.id.container);
			addViewToFrame(mView);

			if (mDeterminateView != null) {
				mDeterminateView.setMax(mMaxProgress);
			}
			if (mIndeterminateView != null) {
				mIndeterminateView.setAnimationSpeed(mAnimateSpeed);
			}

			mLabelText = (TextView) findViewById(com.kaopiz.kprogresshud.R.id.label);
			setLabel(mLabel, mLabelColor);
			mDetailsText = (TextView) findViewById(com.kaopiz.kprogresshud.R.id.details_label);
			setDetailsLabel(mDetailsLabel, mDetailColor);
		}

		private void addViewToFrame(View view) {
			if (view == null) {
				return;
			}
			int wrapParam = ViewGroup.LayoutParams.WRAP_CONTENT;
			ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(wrapParam, wrapParam);
			mCustomViewContainer.addView(view, params);
		}

		private void updateBackgroundSize() {
			ViewGroup.LayoutParams params = mBackgroundLayout.getLayoutParams();
			params.width = Helper.dpToPixel(mWidth, getContext());
			params.height = Helper.dpToPixel(mHeight, getContext());
			mBackgroundLayout.setLayoutParams(params);
		}

		public void setProgress(int progress) {
			if (mDeterminateView != null) {
				mDeterminateView.setProgress(progress);
				if (mIsAutoDismiss && progress >= mMaxProgress) {
					dismiss();
				}
			}
		}

		public void setView(View view) {
			if (view != null) {
				if (view instanceof Determinate) {
					mDeterminateView = (Determinate) view;
				}
				if (view instanceof Indeterminate) {
					mIndeterminateView = (Indeterminate) view;
				}
				mView = view;
				if (isShowing()) {
					mCustomViewContainer.removeAllViews();
					addViewToFrame(view);
				}
			}
		}

		public void setLabel(String label) {
			mLabel = label;
			if (mLabelText != null) {
				if (label != null) {
					mLabelText.setText(label);
					mLabelText.setVisibility(View.VISIBLE);
				} else {
					mLabelText.setVisibility(View.GONE);
				}
			}
		}

		public void setDetailsLabel(String detailsLabel) {
			mDetailsLabel = detailsLabel;
			if (mDetailsText != null) {
				if (detailsLabel != null) {
					mDetailsText.setText(detailsLabel);
					mDetailsText.setVisibility(View.VISIBLE);
				} else {
					mDetailsText.setVisibility(View.GONE);
				}
			}
		}

		public void setLabel(String label, int color) {
			mLabel = label;
			mLabelColor = color;
			if (mLabelText != null) {
				if (label != null) {
					mLabelText.setText(label);
					mLabelText.setTextColor(color);
					mLabelText.setVisibility(View.VISIBLE);
				} else {
					mLabelText.setVisibility(View.GONE);
				}
			}
		}

		public void setDetailsLabel(String detailsLabel, int color) {
			mDetailsLabel = detailsLabel;
			mDetailColor = color;
			if (mDetailsText != null) {
				if (detailsLabel != null) {
					mDetailsText.setText(detailsLabel);
					mDetailsText.setTextColor(color);
					mDetailsText.setVisibility(View.VISIBLE);
				} else {
					mDetailsText.setVisibility(View.GONE);
				}
			}
		}

		public void setSize(int width, int height) {
			mWidth = width;
			mHeight = height;
			if (mBackgroundLayout != null) {
				updateBackgroundSize();
			}
		}
	}

}
